package com.hqyj.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hqyj.dao.ShopMapper;
import com.hqyj.pojo.Shop;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 项目:rabbitmq-230301-provider
 * 描述:
 * 时间:2023/8/4 15:28
 * 作者:admin
 * 版本:1.0
 **/
@Service
@Slf4j
public class ShopServiceImpl implements ShopService {
    //注入shopMapper
    @Resource
    ShopMapper shopMapper;
    //注入mq
    @Autowired
    RabbitTemplate rabbitTemplate;
    //注入redis
    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    @Override
    public synchronized HashMap<String, Object> buy(String shopName, String userName) throws JsonProcessingException, InterruptedException {
        HashMap<String, Object> map = new HashMap<String, Object>();
        //判断用户是否购买这个商品
        Object obj = redisTemplate.opsForHash().get("kill:"+shopName,userName);
        if(obj!=null){
            log.info("用户{}已经买过商品{}",userName,shopName);
            map.put("msg","一个用户只能买一次");
            return map;
        }

        //获取值
        boolean is = redisTemplate.opsForValue().setIfAbsent("suo:"+shopName,1,5,TimeUnit.MINUTES);
        if(!is){
            log.info("上一个用户在处理业务，等待");
            while(!redisTemplate.opsForValue().setIfAbsent("suo:"+shopName,1,5,TimeUnit.MINUTES)){
                Thread.sleep(3000);
            }
        }
        try{
            log.info("用户在处理完成业务");
            //查询商品库存
            Integer stock = queryStock(shopName);
            log.info("商品:{},现有库存:{}",shopName,stock);
            if(stock==0){
                log.info("商品:{}没有库存了",shopName);
                map.put("msg","没有库存了");
                //删除分布锁
                redisTemplate.delete("suo:"+shopName);
                return map;
            }
            //发送消息给mq
            Map<String,Object> p = new HashMap<>() ;
            p.put("shopName",shopName);
            p.put("userName",userName);
            p.put("stock",stock);
            //把p对象转换成json字符串
            ObjectMapper objectMapper = new ObjectMapper();
            String jsonString=objectMapper.writeValueAsString(p);
            CorrelationData data = new CorrelationData(jsonString);
            rabbitTemplate.convertAndSend("shopExchange","shopRoute",p,data);
            log.info("用户{}，抢购商品{}成功",userName,shopName);
            map.put("msg","抢购成功");

        }catch (Exception e){
            e.printStackTrace();
            //删除分布锁
            redisTemplate.delete("suo:"+shopName);
        }

        return map;
    }

    /**
     * 查询某个商品的库存
     * @param shopName 商品名称
     * @return
     */
    private Integer queryStock(String shopName){
        //查询改商品是否有缓存
        Object obj = redisTemplate.opsForValue().get("stock:"+shopName);
        //库存
        int num = 0;
        if(obj==null){
           //查询数据库
            QueryWrapper<Shop> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("shop_name",shopName);
            Shop s = shopMapper.selectOne(queryWrapper);
            //存入缓存中
            redisTemplate.opsForValue().set("stock:"+shopName,s.getShopNumber(),30, TimeUnit.MINUTES);
            num = s.getShopNumber();
        }else{
            num =(Integer) obj;
        }
        return num;
    }

}
